package com.m3958.logcollector.tree;

import com.m3958.logcollector.exception.tree.DuplicatedNodeException;
import com.m3958.logcollector.exception.tree.EmptyNameException;

public class Tree<T> {

    private int jsonLength;

    private String treeName;

    private TreeNode<T> root;

    private TreeAssistant<T> treeAssistant;
    
    public Tree(){
        this.treeAssistant = new TreeAssistant<>(this);
    }
    
    public Tree(long rootId, String rootName, String treeName) {
        TreeNode<T> root = new TreeNode<>(rootId, rootName);
        this.root = root;
        this.treeName = treeName;
        this.treeAssistant = new TreeAssistant<>(this);
    }

    public Tree(TreeNode<T> root, String treeName) {
        this.root = root;
        this.treeName = treeName;
        this.treeAssistant = new TreeAssistant<>(this);
    }

    public TreeNode<T> addChild(long parentId, TreeNode<T> newNode) throws EmptyNameException, DuplicatedNodeException {
        if (newNode.getName() == null || newNode.getName().trim().isEmpty()) {
            throw new EmptyNameException();
        }
        TreeNode<T> parent = findById(parentId);
        if (parent.getChildren().stream().anyMatch(n -> n.getName().equalsIgnoreCase(newNode.getName()))) {
            throw new DuplicatedNodeException();
        }
        parent.addChild(newNode);
        return newNode;
    }

    public void removeNode(long id) {
        TreeNode<T> tn = findById(id);
        if (tn != null) {
            tn.setParent(null);
            tn.getChildren().remove(tn);
            treeAssistant.removeCache(id);
        }
    }

    public TreeNode<T> findById(long id) {
        return treeAssistant.findById(id);
    }

    public TreeNode<T> getRoot() {
        return root;
    }

    public void setRoot(TreeNode<T> root) {
        this.root = root;
    }

    public String getTreeName() {
        return treeName;
    }

    public void setTreeName(String treeName) {
        this.treeName = treeName;
    }

    public int getJsonLength() {
        return jsonLength;
    }

    public void setJsonLength(int jsonLength) {
        this.jsonLength = jsonLength;
    }
}
